home *** CD-ROM | disk | FTP | other *** search
/ CDUTIL 13 / CDUTIL #13 Julio 1995.iso / windows / acadcom / ads / sample / sld2ps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  29.2 KB  |  1,057 lines

  1. /* Next available MSG number is  32 */
  2.  
  3. /*    
  4.  
  5.    SLD2PS.C
  6.  
  7.    Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 by Autodesk, Inc.
  8.  
  9.    Permission to use, copy, modify, and distribute this software in 
  10.    object code form for any purpose and without fee is hereby granted, 
  11.    provided that the above copyright notice appears in all copies and 
  12.    that both that copyright notice and the limited warranty and 
  13.    restricted rights notice below appear in all supporting 
  14.    documentation.
  15.  
  16.    AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.  
  17.    AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF 
  18.    MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
  19.    DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE 
  20.    UNINTERRUPTED OR ERROR FREE.
  21.  
  22.    Use, duplication, or disclosure by the U.S. Government is subject to 
  23.    restrictions set forth in FAR 52.227-19 (Commercial Computer 
  24.    Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) 
  25.    (Rights in Technical Data and Computer Software), as applicable.
  26.     
  27.    .
  28.  
  29.       DESCRIPTION:
  30.  
  31.  
  32.       SLD2PS.C - Converts AutoCAD Slide files to PostScript files
  33.       Optionally outputs full color and Encapsulated PS files.
  34.  
  35.       Designed and implemented by Amar Hanspal, Autodesk Product Support
  36.  
  37.       Originally developed as a DOS stand-alone program - January 89
  38.       Converted to Release 11 ADS application           - March 90
  39.  
  40. */
  41.  
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <ctype.h>
  45.  
  46. #include "adslib.h"
  47.  
  48. #define ushort unsigned short
  49. #define uchar  unsigned char
  50.  
  51. /* Hardcopy parameters */
  52.  
  53. #define PSIZEX 8.50                   /* X Paper size in inches */
  54. #define PSIZEY 11.00                  /* Y Paper size in inches */
  55. #define HCLIP 0.125                   /* Printer's hardclip limits */
  56.  
  57. #define DPI 72.0                      /* PostScript's Units per inch */
  58.  
  59. #define PLOWX 0.5                     /* Half-inch border around plot */
  60. #define PLOWY 0.5
  61. #define PHIGHX (PSIZEX - 0.5)
  62. #define PHIGHY (PSIZEY - 0.5)
  63.  
  64. #define LOWXDOT PLOWX*DPI             /* Convert to PostScript units */
  65. #define LOWYDOT PLOWY*DPI
  66. #define HIXDOT  PHIGHX*DPI
  67. #define HIYDOT  PHIGHY*DPI
  68. #define HCLIPADJ HCLIP*DPI
  69.  
  70. /* Define the record types present in a Slide file */
  71.  
  72. #define MINVEC          0x0000        /* Plain vector - minimum value */
  73. #define MAXVEC          0x7F00        /* Plain vector - maximum value */
  74. #define OFFSETVEC       0xFB00        /* Offset from last vector */
  75. #define ENDOFSLD        0XFC00        /* End of Slide File marker */
  76. #define SOLIDFILL       0xFD00        /* Solid Fill */
  77. #define COMMONEND       0xFE00        /* Common endpoint with last vector */
  78. #define NEWCOLOR        0xFF00        /* New color begins */
  79.  
  80. /* Declare global variables */
  81.  
  82. unsigned short lowx = 0, lowy = 0 ;   /* Drawing limits */
  83. unsigned short highx= 0, highy = 0;   /* Ditto */
  84. unsigned short plastx = 0, plasty = 0;/* PostScript's last X & Y point */
  85. FILE *in = NULL, *out = NULL;         /* Input and output file pointers */
  86. char *exfun = /*MSG0*/"C:SLD2PS";     /* AutoCAD Command name */
  87.  
  88. /* Declare global flags */
  89.  
  90. char lptok = 0;                       /* Last point OK flag */
  91. char scrout = 0;                      /* = 1 if printing the screen */
  92. char colorout = 0;                    /* = 1 if color */
  93. char epsout = 0;                      /* = 1 if encapsulated */
  94. char boxout = 0;                      /* = 1 if drawing a plotbox */
  95. char rotate = 0;                      /* = 1 if landscape */
  96. char oldformat = 0;                   /* = 1 if pre-R9 style slide file */
  97. char backwards = 0;                   /* = 1 if file needs byte swapping */
  98. char usrcanc = 0;                     /* = 0 if user cancels the function */
  99. char intel = 0 ;                      /* = 1 if running on an Intel chip */
  100.  
  101. /* Forward Function declarations */
  102.  
  103. void main _((int argc, char **argv));         /* ADS link */
  104. void clearopts _((void));             /* Clear old options */
  105. int funcload _((void));               /* ADS function load routine */
  106. int funcunload _((void));             /* ADS function unload routine */
  107. int dofun _((void));                  /* ADS function dispatcher */
  108. int sld2ps _((void));                 /* Main routine */
  109. void endplot _((void));               /* Closes PostScript file */
  110. void drawbox _((void));               /* Draws a border */
  111.  
  112. #ifdef __ZTC__
  113. void initplot _((double pscfx, double pscfy));
  114. void swap_pen _((int pen));
  115. int drawvec _((int x1, int y1, int x2, int y2));
  116. int contvec _((int x2, int y2));
  117. void raisepen _((int curx, int cury));
  118. int sfill _((int sx2, int sy2, int fillstat));
  119. short fixchar _((int ch));
  120. #else  /* __ZTC__ */
  121. #if defined(__WATCOMC__) || defined(TURBOC) || defined(sun)
  122. void initplot _((double pscfx, double pscfy));
  123. #else
  124. void initplot _((float pscfx, float pscfy));         /* Opens PostScript file */
  125. #endif
  126. void swap_pen _((short pen));         /* Handles color output */
  127. int drawvec _((ushort x1, ushort y1, ushort x2, ushort y2));
  128. int contvec _((ushort x2, ushort y2));
  129. void raisepen _((ushort curx, ushort cury));
  130. int sfill _((short sx2, short sy2, char fillstat));  /* Handles solid fill */
  131. short fixchar _((unsigned char ch));  /* Simple read routine to help out */
  132. #endif  /* __ZTC__ */
  133.  
  134. short fetch2bytes _((void));          /* Simple read routine to help out */
  135. short fetchoffset _((void));          /* Ditto */
  136. int formshort _((unsigned char *ptr));  /* The short of portability */
  137. int formlong _((unsigned char *ptr));   /* The long of portability */
  138. int testlong _((unsigned char *ptr));   /* Tests CPU storage of long integers */
  139. int printscr _((void));               /* Creates a temporary slide file */
  140. int getyorn _((char *question));       /* Asks questions, sets global flags */
  141.  
  142.  
  143. void main(argc,argv)
  144.   int argc;
  145.   char *argv[];
  146. {
  147.  
  148.     /* Local declarations */
  149.  
  150.     short scode = RSRSLT;             /* normal result code */
  151.     int stat;
  152.     char errmsg[80];
  153.  
  154.     /* Actual Code begins here */
  155.  
  156.     ads_init(argc, argv);
  157.  
  158.     for ( ;; ) {
  159.  
  160.         if ((stat = ads_link(scode)) < 0)  {
  161.             sprintf(errmsg,
  162.                     /*MSG1*/"SLD2PS: bad status from ads_link() = %d\n",
  163.                     stat);
  164. #ifdef Macintosh
  165.             macalert(errmsg);
  166. #else
  167.             puts(errmsg);
  168.             fflush(stdout);
  169. #endif /* Macintosh */
  170.             ads_exit(1);
  171.         }
  172.  
  173.         scode = RSRSLT;               /* default return code */
  174.  
  175.         switch (stat)  {
  176.  
  177.         case RQXLOAD:
  178.             scode = funcload() ? -RSRSLT : -RSERR;
  179.             continue;
  180.  
  181.         case RQXUNLD:                 /* Unloading */
  182.             scode = (funcunload() ? RSRSLT : RSERR);
  183.             break;
  184.  
  185.         case RQSUBR:
  186.             dofun();
  187.             ads_retvoid();            /* Exit queitly */
  188.             break;
  189.  
  190.         default:
  191.             break;
  192.  
  193.         }                             /* End switch */
  194.  
  195.     }                                 /* End for */
  196.  
  197. }                                     /* End main */
  198.  
  199. /* FUNCLOAD - Load external functions  */
  200.  
  201. int funcload()
  202. {
  203.     if (ads_defun(exfun,0) != RTNORM)
  204.         return 0;
  205.     else
  206.         return 1;
  207. }
  208.  
  209. /* FUNCUNLOAD - Unload external functions */
  210.  
  211. int funcunload()
  212. {
  213.     ads_undef(exfun,0);
  214.  
  215.     return 1;
  216. }
  217.  
  218. /* DOFUN - Process the RQSUBR call from AutoCAD */
  219.  
  220. int dofun()
  221. {
  222.     int val;
  223.  
  224.     if ( (val = ads_getfuncode()) < 0)
  225.         return 0;
  226.     else {
  227.         switch (val) {
  228.  
  229.         case 0:
  230.             return sld2ps();
  231.  
  232.         default:
  233.             break;
  234.         }
  235.  
  236.     }
  237.  
  238.     return 1;
  239.  
  240. }
  241.  
  242. /* SLD2PS - Reads and process the slide file */
  243.  
  244. int sld2ps()
  245. {
  246.  
  247.     /* Slide file header fields */
  248.  
  249.     char id[17];                      /* Slide file banner */
  250.     char typeind, levlind;            /* Header information */
  251.     short hfill, testno;              /* Hardware fill & test number */
  252.     long aspect;                      /* Aspect Ratio encoded as long */
  253.  
  254.     /* Alternate fields for OLD format slide files */
  255.  
  256.     double oldasp;                    /* Old format aspect ratio */
  257.     short oldhfill;                   /* Old hardware fill */
  258.     char fillbyte;                    /* Padding around old format file */
  259.  
  260.     /* Local variables */
  261.  
  262.     static char sldfile[132], plotfile[132];  /* Filename strings */
  263.  
  264.     float gscf;                       /* PostScript Scale Factor */
  265.     float xscf, yscf, scly;           /* X, Y & Scaled Y Scale factors */
  266.  
  267.     unsigned short fromx, fromy, tox, toy;    /* Vector co-ordinates */
  268.     unsigned short lastx = 0, lasty = 0;      /* Last point saved */
  269.     short sfx, sfy  = 0;              /* Running Solid fill co-ords */
  270.  
  271.     unsigned short rtype = 0x00;      /* Slide file record type flag */
  272.     short color = 0x07;               /* Initialize color to white or black */
  273.     short offset;                     /* +/- 127 Offset buffer */
  274.  
  275.     char fillon = 0;                  /* Fill in progress ? */
  276.     char firstpass = 0;               /* First time through ? */
  277.  
  278.     char lobyte;                      /* Low byte value */
  279.     unsigned short cword;             /* 2 byte integer from "    */
  280.  
  281.     register unsigned short j = 0;    /* Processing vector counter */
  282.  
  283.     /* Begin */
  284.  
  285.     clearopts ();                     /* Clear previous flags */
  286.  
  287.     scrout = getyorn(/*MSG2*/"\nWould you like to plot the display ? <No>: ");
  288.  
  289.     if (usrcanc)                      /* We're aborting */
  290.         return 0 ;
  291.  
  292.     if (scrout) {
  293.         if (!printscr()) {
  294.             ads_fail(/*MSG3*/"Error creating temporary slide file.");
  295.             return 0;
  296.         }
  297.         strcpy(sldfile,/*MSG0*/"sld2ps");
  298.     }
  299.     else {
  300.         ads_getstring (0,/*MSG4*/"\nEnter the name of Slide File to process: ",
  301.                        sldfile);
  302.     }
  303.  
  304.     if (sldfile[0] == 0) {
  305.         ads_fail (/*MSG5*/"Slide file name must be specified.\n");
  306.         return 0;
  307.     }
  308.  
  309.     strcpy (plotfile, sldfile);
  310.     strcat (sldfile,/*MSG0*/".sld");
  311.  
  312.     if ((in = fopen (sldfile,/*MSG0*/"rb")) == NULL)  {
  313.         ads_fail (/*MSG6*/"Error opening slide file.\n");
  314.         return 0;
  315.     }
  316.  
  317.     /* Get answers to some major questions about life */
  318.  
  319.     colorout = getyorn
  320.                (/*MSG7*/"\nDo you want Color PostScript Output ? <No>: ");
  321.     if (usrcanc) return 0 ;
  322.  
  323.     epsout = getyorn
  324.              (/*MSG8*/"\nDo you want Encapsulated PostScript Output ? <No>: ");
  325.     if (usrcanc) return 0 ;
  326.  
  327.     rotate = getyorn
  328.              (/*MSG9*/"\nDo you want to rotate the output ? <No>: ");
  329.     if (usrcanc) return 0 ;
  330.  
  331.     boxout = getyorn
  332.              (/*MSG10*/"\nDo you want a border around the plot ? <No>: ");
  333.     if (usrcanc) return 0;
  334.  
  335.     if (epsout == 1)
  336.         strcat (plotfile,/*MSG0*/".eps");
  337.     else
  338.         strcat (plotfile,/*MSG0*/".ps" );
  339.  
  340.     ads_printf (/*MSG11*/"\nInput slide file %s, Output PostScript file %s.\n",
  341.                 sldfile, plotfile);
  342.  
  343.     if (colorout == 1)
  344.         ads_printf (/*MSG12*/"\nFull Color: RGB triples will be output.");
  345.     else
  346.         ads_printf (/*MSG13*/"\nMonochrome output assumed.");
  347.  
  348.     if (epsout == 1)
  349.         ads_printf (/*MSG14*/"\nGenerating Encapsulated PostScript file.");
  350.  
  351.     if (rotate == 1)
  352.         ads_printf (/*MSG15*/"\nRotating plots to landscape orientation. ");
  353.  
  354.     if ((out = fopen(plotfile,/*MSG0*/"wb")) == NULL) {
  355.         ads_fail (/*MSG16*/"Error opening plot file.\n");
  356.         return 0;
  357.     }
  358.  
  359.     /* Read in from slide file: Assume Release 9 Slide file format */
  360.  
  361.     fread (id,17,1,in);
  362.     fread (&typeind,sizeof(typeind),1,in);
  363.     fread (&levlind,sizeof(levlind),1,in);
  364.     fread (&highx,sizeof(highx),1,in);
  365.     fread (&highy,sizeof(highy),1,in);
  366.  
  367.     if (levlind == 1)
  368.         oldformat = 1;
  369.  
  370.     if (!oldformat) {
  371.         fread (&aspect,sizeof(aspect),1,in);
  372.         fread (&hfill,sizeof(hfill),1,in);
  373.         fread (&testno,sizeof(testno),1,in);
  374.     }
  375.     else {
  376.         fread (&oldasp,sizeof(oldasp),1,in);
  377.         fread (&oldhfill,sizeof(oldhfill),1,in);
  378.         fread (&fillbyte,sizeof(fillbyte),1,in);
  379.     }
  380.  
  381.     if ( (strncmp(id,/*MSG0*/"AutoCAD Slide", 13)) != 0) {
  382.         ads_fail (/*MSG17*/"Invalid slide file header! Aborting.\n");
  383.         return 0;
  384.     }
  385.  
  386.     if (testno != 0x1234)
  387.         backwards = 1;                /* File written in reverse byte order */
  388.  
  389.     if (!oldformat) {
  390.         formshort ((unsigned char *)&highx);
  391.         formshort ((unsigned char *)&highy);
  392.         formshort ((unsigned char *)&hfill);
  393.         formlong  ((unsigned char *)&aspect);
  394.     }
  395.  
  396.  
  397.     if (oldformat) {
  398.         ads_printf (/*MSG18*/"\n\nSlide file was written in old format.");
  399.         ads_printf (/*MSG19*/"\nNo byte-ordering check possible.");
  400.     }
  401.     else {
  402.         ads_printf (/*MSG20*/"\n\nSlide file was written in Release 9 format.");
  403.  
  404.         if (backwards)
  405.             ads_printf (/*MSG21*/"\nSwapping bytes while reading file.");
  406.         else
  407.             ads_printf (/*MSG22*/"\nNo byte-swapping neccessary.");
  408.     }
  409.  
  410.     ads_printf (/*MSG23*/"\nSlide file resolution is %u x %u pixels.",
  411.                 highx + 1, highy + 1);
  412.  
  413.     ads_printf ("\n\n");
  414.  
  415.     /* Calculate X & Y scale factors as: Paper size/Highest X or Y pixel */
  416.     /* If plots are rotated, the X & Y PAPER directions are reversed */
  417.  
  418.     if (rotate == 1)  {
  419.         xscf =  (HIYDOT - LOWYDOT - 2*HCLIPADJ)/(float)highx;
  420.         yscf =  (HIXDOT - LOWXDOT - 2*HCLIPADJ)/(float)highy;
  421.     }
  422.     else {
  423.         xscf =  (HIXDOT - LOWXDOT - 2*HCLIPADJ)/(float)highx;
  424.         yscf =  (HIYDOT - LOWYDOT - 2*HCLIPADJ)/(float)highy;
  425.     }
  426.  
  427.     gscf =  (xscf < yscf) ? xscf : yscf;  /* Global scale is higher of 2 */
  428.  
  429.     if (!oldformat)
  430.         scly =  aspect/1e7*(float)highy;     /* Scale Y using aspect ratio */
  431.     else
  432.         scly = oldasp*(float)highy;
  433.  
  434.     yscf =  gscf*(float)highx/scly;          /* Scale the Y factor by global factor */
  435.  
  436.     /* Start plot */
  437.  
  438.     initplot (xscf, yscf);
  439.  
  440.     if (boxout == 1)
  441.         drawbox();
  442.  
  443.     /* Start parsing data */
  444.  
  445.     while ( (cword = (ushort)fetch2bytes() ) != ENDOFSLD) {
  446.  
  447.         lobyte = (cword & 0x00FF);
  448.         rtype = (cword & 0xFF00);     /* High order byte marks record type */
  449.  
  450.         switch (rtype) {
  451.  
  452.         case OFFSETVEC:
  453.  
  454.             offset = fixchar((uchar)lobyte);
  455.             fromx = lastx + offset;
  456.  
  457.             offset = fetchoffset();
  458.             fromy = lasty + offset;
  459.  
  460.             offset = fetchoffset();
  461.             tox = lastx + offset;
  462.  
  463.             offset = fetchoffset();
  464.             toy = lasty + offset;
  465.  
  466.             /* Output vector */
  467.  
  468.             drawvec (fromx, fromy, tox, toy);
  469.  
  470.             /* Save last point */
  471.  
  472.             lastx = fromx;
  473.             lasty = fromy;
  474.  
  475.             break;
  476.  
  477.         case ENDOFSLD:
  478.             /* Nothing to do */
  479.             break;
  480.  
  481.         case SOLIDFILL:
  482.  
  483.             sfx = fetch2bytes();
  484.             sfy = fetch2bytes();
  485.  
  486.             /* Toggle fill on/off if negative Y value */
  487.  
  488.             if (sfy < 0)
  489.                 fillon = (fillon == 0) ? 1 : 0;
  490.  
  491.             /* Output point to fill routine */
  492.  
  493.             sfill (sfx, sfy, fillon);
  494.  
  495.             /* Last point is no longer OK ! */
  496.  
  497.             lptok = 1;
  498.  
  499.             break;
  500.  
  501.         case COMMONEND:
  502.  
  503.             fromx = lastx;
  504.             fromy = lasty;
  505.  
  506.             offset = fixchar(lobyte);
  507.             tox = lastx + offset;
  508.  
  509.             offset = fetchoffset();
  510.             toy = lasty + offset;
  511.  
  512.             /* Output vector */
  513.  
  514.             drawvec (fromx, fromy, tox, toy);
  515.  
  516.             /* Save point */
  517.  
  518.             lastx = tox;
  519.             lasty = toy;
  520.  
  521.             break;
  522.  
  523.         case NEWCOLOR:
  524.  
  525.             color = lobyte;
  526.  
  527.             if (colorout == 1) {
  528.                 if (firstpass != 0)
  529.                     raisepen (lastx,lasty);
  530.                 swap_pen(color);
  531.                 firstpass = 1;
  532.             }
  533.  
  534.             break;
  535.  
  536.         default:
  537.             /* Should be vector def; else oops ! */
  538.  
  539.             if (rtype <= MAXVEC)  {
  540.  
  541.                 fromx = cword;
  542.                 fromy = fetch2bytes();
  543.                 tox   = fetch2bytes();
  544.                 toy   = fetch2bytes();
  545.  
  546.                 drawvec (fromx, fromy, tox, toy);
  547.  
  548.                 lastx = fromx;
  549.                 lasty = fromy;
  550.             }
  551.             else
  552.                 ads_printf(/*MSG24*/"\nUnknown code %x in slide file! ", rtype);
  553.  
  554.             break;
  555.  
  556.  
  557.         }                             /* End switch */
  558.  
  559.         j++;
  560.  
  561.  
  562.         if (j % 32 == 0)  {
  563.             ads_printf(/*MSG25*/"\rProcessing vector %u", j );
  564.             if ( ads_usrbrk() ) {
  565.                 ads_fail(/*MSG30*/"Function cancelled. ") ;
  566.                 endplot () ;
  567.                 return 0 ;
  568.             }
  569.         }
  570.  
  571.         if (j % 150 == 0 && fillon == 0 )
  572.             raisepen (lastx, lasty);
  573.  
  574.  
  575.     }                                 /* End while */
  576.  
  577.     endplot ();
  578.     ads_printf (/*MSG26*/"\n\nDone ! Output file %s created!\n", plotfile);
  579.  
  580.     return 1;
  581. }
  582.  
  583. /* INITPLOT - Opens and constructs the Header of the PostScript file */
  584.  
  585. void initplot(pscfx, pscfy)
  586.   float pscfx;
  587.   float pscfy;
  588. {
  589.     if (epsout == 1) {                /* Special header for Encapsulated file */
  590.         fprintf (out,/*MSG0*/"%%!PS-Adobe-2.0 EPSF-1.2\n");
  591.         fprintf (out,/*MSG0*/"%%%%Bounding Box: %u %u %u %u\n",
  592.                  lowx, lowy, highx, highy) ;
  593.         fprintf (out,/*MSG0*/"%%%%Creator: File from SLD2PS\n");
  594.         fprintf (out,/*MSG0*/"%%%%EndComments\n");
  595.     }
  596.     else {
  597.         fprintf (out,/*MSG0*/"%%!PS-Adobe-1.0\n");
  598.         fprintf (out,/*MSG0*/"%%%%Creator: File from SLD2PS\n");
  599.         fprintf (out,/*MSG0*/"%%%%EndComments\n");
  600.     }
  601.  
  602.     fprintf (out,/*MSG0*/"/m {moveto} def\n");
  603.     fprintf (out,/*MSG0*/"/l {lineto} def\n");
  604.     fprintf (out,/*MSG0*/"/s {stroke} def\n");
  605.     fprintf (out,/*MSG0*/"/f {fill} def\n");
  606.     fprintf (out,/*MSG0*/"/n {newpath} def\n");
  607.     fprintf (out,/*MSG0*/"1 setlinejoin\n");
  608.     fprintf (out,/*MSG0*/"0.5 setlinewidth\n");
  609.     fprintf (out,/*MSG0*/"1 setlinecap\n");
  610.  
  611.     if (rotate == 1)  {               /* Reset origin & re-align co-ords */
  612.         fprintf (out,/*MSG0*/"90 rotate\n");
  613.         fprintf (out,/*MSG0*/"0 %f translate\n", -1.0*DPI*PSIZEX);
  614.         fprintf (out,/*MSG0*/"%f %f translate\n", LOWXDOT, LOWYDOT);
  615.     }
  616.     else
  617.         fprintf (out,/*MSG0*/"%f %f translate\n", LOWXDOT, LOWYDOT);
  618.  
  619.     fprintf (out,/*MSG0*/"%5.3f %5.3f scale\n", pscfx, pscfy);
  620.     fprintf (out,/*MSG0*/"n\n");
  621.  
  622.     return;
  623. }
  624.  
  625. /* ENDPLOT - Completes PostScript file */
  626.  
  627. void endplot()
  628. {
  629.     fprintf (out,/*MSG0*/"s\n");
  630.  
  631.     if (epsout != 1)
  632.         fprintf (out,/*MSG0*/"%%%%Bounding Box %u %u %u %u\n",
  633.                  lowx, lowy, highx, highy);
  634.  
  635.     fprintf (out,/*MSG0*/"showpage\n");
  636.  
  637.     fclose (in) ;
  638.     fclose (out) ;
  639.  
  640.     return;
  641. }
  642.  
  643. /* DRAWBOX - Draws a nice rectangular border around plot */
  644.  
  645. void drawbox()
  646. {
  647.     fprintf (out,/*MSG0*/"%u %u m\n", lowx, lowy);
  648.     fprintf (out,/*MSG0*/"%u %u l\n", highx, lowy);
  649.     fprintf (out,/*MSG0*/"%u %u l\n", highx, highy);
  650.     fprintf (out,/*MSG0*/"%u %u l\n", lowx, highy);
  651.     fprintf (out,/*MSG0*/"%u %u l\n", lowx, lowy);
  652.     fprintf (out,/*MSG0*/"s\n");
  653.     return;
  654. }
  655.  
  656. /* SWAP_PEN - Outputs PostScript RGB triple from AutoCAD HSV color */
  657. /* Adapted from Foley and Van Dam and some ADI documentation */
  658.  
  659. #ifdef __STDC__
  660. void swap_pen(short pen)
  661. #else
  662. void swap_pen(pen)
  663.   short pen;
  664. #endif
  665. {
  666.     unsigned char acadclr;                      /* AutoCAD color number */
  667.     float red = 0.0, green = 0.0, blue = 0.0;   /* RGB triplet values */
  668.     float hue, sat, val;                        /* HSV components */
  669.     static float bright[5] = {
  670.             1.0, 0.65, 0.5, 0.3, 0.15       };
  671.     int i, vs;
  672.     float f;
  673.     float p,q,t;
  674.     int visible = 0;                  /* Force white visibility is off */
  675.  
  676.  
  677.     /* Begin */
  678.  
  679.     acadclr = pen ;
  680.  
  681.     if (acadclr >= 250 && acadclr <= 255)  {
  682.         red = 1;
  683.         green = 0.5;                  /* These RGB choices are arbitrary */
  684.         blue = 0.35;
  685.         visible = 1;                  /* Make sure it comes out ; force black */
  686.     }
  687.     else {
  688.  
  689.         switch (acadclr) {
  690.  
  691.         case 1 :                      /* Red */
  692.             red = 1;
  693.             blue = 0;
  694.             green = 0;
  695.             break;
  696.  
  697.         case 2 :                      /* Yellow */
  698.             red = 1;
  699.             green = 1;
  700.             blue = 0;
  701.             break;
  702.  
  703.         case 3 :                      /* Green */
  704.             red = 0;
  705.             green = 1;
  706.             blue = 0;
  707.             break;
  708.  
  709.         case 4 :                      /* Cyan */
  710.             red = 0;
  711.             green = 1;
  712.             blue = 1;
  713.             break;
  714.  
  715.         case 5:                       /* Blue */
  716.             red = 0;
  717.             green = 0;
  718.             blue = 1;
  719.             break;
  720.  
  721.         case 6:                       /* Magenta */
  722.             red = 1;
  723.             green = 0;
  724.             blue = 1;
  725.             break;
  726.  
  727.         case 0 :                      /* Just in case someone screws up */
  728.  
  729.         case 7 :                      /* White */
  730.         case 8 :
  731.         case 9 :
  732.             red = 1;
  733.             green = 1;
  734.             blue = 1;
  735.             visible = 1;              /* Force black output on paper */
  736.             break;
  737.  
  738.         default :                     /* For colors between 10 & 250 */
  739.  
  740.             hue =  ((float)acadclr - 10) / 10.0; /* 240 maps to 0 - 6 */
  741.  
  742.             if (hue >= 24)
  743.                 hue -= 24;
  744.             hue = hue / 4.0;
  745.  
  746.             vs =   acadclr % 10;      /* Encoded Saturation and Value */
  747.  
  748.             val =  bright[vs >> 1];   /* this should be 0,2,4,6,8 */
  749.             sat =  vs & 1 ? 0.5 : 1.0;    /* if odd, set it to 0.5, else 1 */
  750.  
  751.             i = (int)hue;
  752.             f = hue - i;              /* Fractional part of Hue */
  753.  
  754.             p = val*(1 - sat);
  755.             q = val*(1 - (sat*f));
  756.             t = val*(1 - (sat*(1 - f)));
  757.  
  758.             switch (i)        {
  759.  
  760.             case 0 :
  761.                 red = val;
  762.                 green = t;
  763.                 blue = p;
  764.                 break;
  765.  
  766.             case 1 :
  767.                 red = q;
  768.                 green = val;
  769.                 blue = p;
  770.                 break;
  771.  
  772.             case 2 :
  773.                 red = p;
  774.                 green = val;
  775.                 blue = t;
  776.                 break;
  777.  
  778.             case 3 :
  779.                 red = p;
  780.                 green = q;
  781.                 blue = val;
  782.                 break;
  783.  
  784.             case 4 :
  785.                 red = t;
  786.                 green = p;
  787.                 blue = val;
  788.                 break;
  789.  
  790.             case 5 :
  791.                 red = val;
  792.                 green = p;
  793.                 blue = q;
  794.                 break;
  795.  
  796.             default :
  797.                 ads_printf (/*MSG27*/"Unknown color code : %d %f %f %f %f\n",
  798.                             acadclr, hue,sat, val);
  799.  
  800.             }                         /* Switch (i) */
  801.  
  802.         }                             /* Switch (acadclr) */
  803.  
  804.     }                                 /* Else (acadclr < 250) */
  805.  
  806.     if (visible == 1)
  807.         fprintf (out,/*MSG0*/"0 0 0 setrgbcolor\n");    /* Pure black ! */
  808.     else
  809.         fprintf (out,/*MSG0*/"%f %f %f setrgbcolor\n", red, green, blue);
  810.  
  811.     return;
  812. }
  813.  
  814. /* DRAWVEC - Outputs PostScript vector to file */
  815.  
  816. #ifdef __STDC__
  817. int drawvec(unsigned short x1,
  818.             unsigned short y1,
  819.             unsigned short x2,
  820.             unsigned short y2)
  821. #else
  822. int drawvec(x1, y1, x2, y2)
  823.   unsigned short x1, y1, x2, y2;
  824. #endif
  825. {
  826.  
  827.     /*   See if from point is the same as the last saved point
  828.          If so, continue the vector, rather than output a full one
  829.          Note that PostScript's "last point" is the exact opposite of
  830.          the slide file's last point. PostScript uses the "to" point
  831.          Also avoid continuing a vector if lastpoint is invalid following
  832.          a fill.
  833.     */
  834.  
  835.     if (x1 == plastx && y1 == plasty && lptok == 0)
  836.         contvec (x2, y2);
  837.     else {
  838.         fprintf (out,/*MSG0*/"%u %u m\n", x1, y1);
  839.         fprintf (out,/*MSG0*/"%u %u l\n", x2, y2);
  840.     }
  841.  
  842.     plastx = x2;
  843.     plasty = y2;
  844.  
  845.     lptok = 0;
  846.  
  847.     return 1;
  848. }
  849.  
  850. /* CONTVEC - Continues last vector */
  851. #ifdef __STDC__
  852. int contvec(unsigned short x2,
  853.             unsigned short y2)
  854. #else
  855. int contvec(x2, y2)
  856.   unsigned short x2, y2;
  857. #endif
  858. {
  859.     fprintf (out,/*MSG0*/"%u %u l\n", x2, y2);
  860.  
  861.     return 1;
  862. }
  863.  
  864. /* RAISEPEN - Strokes current path when PostScript path has reached max points */
  865. #ifdef __STDC__
  866. void raisepen(unsigned short curx,
  867.               unsigned short cury)
  868. #else
  869. void raisepen(curx, cury)
  870.   unsigned short curx, cury;
  871. #endif
  872. {
  873.     fprintf (out,/*MSG0*/"s\n");
  874.     fprintf (out,/*MSG0*/"%u %u m\n", curx, cury);
  875.  
  876.     lptok = 1;                        /* Warn vector drawing function */
  877.  
  878.     return;
  879. }
  880.  
  881. /* SFILL - Generates Solid Fill Polygon */
  882. #ifdef __STDC__
  883. int sfill(short sx2, short sy2, char fillstat)
  884. #else
  885. int sfill(sx2, sy2, fillstat)
  886.   short sx2, sy2;                     /* Fill polygon co-ordinates */
  887.   char fillstat;                      /* Is fill beginning or ending ? */
  888. #endif
  889. {
  890.     static int call;
  891.  
  892.     if (sy2 < 0 && fillstat == 1)
  893.         call = 1;                     /* Start of fill, nothing to do */
  894.     else
  895.     if (sy2 > 0) {
  896.         if (call == 1) {              /* First fill point. End current path
  897.                                          and move to start point */
  898.             fprintf (out,/*MSG0*/"s\n");
  899.             fprintf (out,/*MSG0*/"%d %d m\n", sx2, sy2);
  900.             call++;
  901.         }                             /* Output fill polygon point */
  902.         else
  903.             fprintf (out,/*MSG0*/"%d %d l\n", sx2, sy2);
  904.     }
  905.  
  906.     if (sy2 < 0 && fillstat == 0) {   /* End of fill */
  907.         call = 0;
  908.         fprintf (out,/*MSG0*/"f\n");
  909.     }
  910.  
  911.     return 1;
  912.  
  913. }
  914.  
  915. /* FETCH2BYTES - Read a 2 byte integer in a portable fashion */
  916.  
  917. short fetch2bytes()
  918. {
  919.     short wd = 0 ;
  920.  
  921.     fread (&wd, sizeof(wd), 1, in) ;
  922.  
  923.     if (!oldformat) {
  924.         if (backwards)
  925.             wd = ((wd >> 8) & 0xFF) | (wd << 8) ;
  926.     }
  927.  
  928.     return wd ;
  929. }
  930.  
  931. /* FETCHOFFSET - Fetches a 1 byte short */
  932.  
  933. short fetchoffset()
  934. {
  935.     unsigned char ch = 0;
  936.  
  937.     fread (&ch, sizeof(ch) , 1, in);
  938.  
  939.     return fixchar(ch);
  940. }
  941.  
  942. /* FIXCHAR - Converts a char to a short, hammers in sign bit */
  943.  
  944. #ifdef __STDC__
  945. short fixchar(unsigned char ch)
  946. #else
  947. short fixchar(ch)
  948.   unsigned char ch;
  949. #endif
  950. {
  951.     return ( (short) ((ch & 0x80) ? ch | ~0xFF : ch));
  952. }
  953.  
  954. /* FORMSHORT - Swaps bytes of a short depending on machine type */
  955.  
  956. int formshort(ptr)
  957.   unsigned char *ptr;                 /* Pointer to data array */
  958. {
  959.     register unsigned char swap;
  960.  
  961.     if (backwards) {
  962.         swap   = ptr[0];
  963.         ptr[0] = ptr[1];
  964.         ptr[1] = swap;                /* Swap those bytes ! */
  965.     }
  966.  
  967.     return 1;
  968. }
  969.  
  970. /* FORMLONG - Form a 4 byte long integer */
  971.  
  972. int formlong(ptr)
  973.   unsigned char *ptr;                 /* Pointer to data array */
  974. {
  975.     unsigned long testval = 1L;       /* Test value */
  976.     register unsigned char swap;
  977.  
  978.     testlong ((unsigned char *)&testval);      /* Test to check CPU type */
  979.  
  980.     if (!intel) {
  981.         swap   = ptr[0];
  982.         ptr[0] = ptr[3];
  983.         ptr[3] = swap;
  984.         swap   = ptr[1];
  985.         ptr[1] = ptr[2];
  986.         ptr[2] = swap;
  987.     }                                 /* AutoCAD always writes longs with LSB */
  988.                                       /* first, so Intel CPUs don't need help */
  989.  
  990.     return 1;
  991. }
  992.  
  993. /* TESTLONG - Checks to see if the CPU stores longs with LSB first or HSB first */
  994.  
  995. int testlong(ptr)
  996.   unsigned char *ptr;
  997. {
  998.     char lsb = 0;
  999.  
  1000.     lsb = ptr[0];                     /* Get first byte */
  1001.  
  1002.     if (lsb == 1)
  1003.         intel = 1;                    /* Intel style CPUs store LSB first */
  1004.  
  1005.     return 1 ;
  1006.  
  1007. }
  1008.  
  1009. /* PRINTSCR - Creates a temporary slide file of the current display */
  1010.  
  1011. int printscr()
  1012. {
  1013.     ads_printf (/*MSG28*/"\nCreating temporary slide file SLD2PS.SLD\n");
  1014.  
  1015.     if ( (ads_command (RTSTR,/*MSG29*/"_.MSLIDE", RTSTR,/*MSG0*/"sld2ps",
  1016.                        RTNONE) ) < 0)
  1017.         return 0;
  1018.     else
  1019.         return 1;
  1020. }
  1021.  
  1022. /* GETOPT - Gets a simple yes or no from the user, to set a global flag */
  1023.  
  1024. int getyorn(question)
  1025.   char *question;
  1026. {
  1027.     static char opt, optstr[132];
  1028.  
  1029.     opt = /*MSG0*/'n';                /* Set default option */
  1030.  
  1031.     if ( (ads_getstring (0,question,optstr)) == RTCAN)  {
  1032.         usrcanc = 1 ;
  1033.         ads_fail (/*MSG31*/"Function cancelled.") ;
  1034.         return 0 ;
  1035.     }
  1036.  
  1037.     opt = optstr[0];
  1038.  
  1039.     if (toupper(opt) == /*MSG0*/'Y')
  1040.         return 1;
  1041.     else
  1042.         return 0;
  1043. }
  1044.  
  1045. /* CLEAROPTS - Clears previously set flags and options from last RQSUBR */
  1046. /* The application is loaded and initialized only once, but could be executed */
  1047. /* several times.  Flags not cleared would be affect the next execution */
  1048.  
  1049. void clearopts()
  1050. {
  1051.     backwards = lptok = scrout = colorout = 0;
  1052.     epsout = boxout = rotate = oldformat = 0;
  1053.     usrcanc = 0 ;
  1054.  
  1055.     return;
  1056. }
  1057.